package Grafica;

import java.awt.event.*;
import javax.swing.*;
import Entidades.ElementoJuego;
import Entidades.Gravedad;
import Entidades.Mario;
import Entidades.MarioChico;
import Nivel.Tablero;

/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
@SuppressWarnings("serial")
public class GuiJuego extends javax.swing.JFrame implements Runnable{

	private Tablero nivel;

	private Gravedad gravedad;
	private Mario mario;

	private Thread hiloGravedad;
	private Thread hiloMario;
	private Thread hiloJuego;

	private JLabel imageBackground;
	private JPanel panelElementos;

	private JPanel panel;
	private JPanel contenedorPersonaje;
	
	private boolean bloquearAvanzar, 
					bloquearRetroceder, 
					bloquearSaltar = false,
					
					findejuego = false;
	
	private ActualizadorAvanzar avanzar;
	private ActualizadorRetroceder retroceder;
	private ActualizadorSaltar saltar;
	
	public GuiJuego(String mapa) {
		super("Super Mario");
		nivel = new Tablero(mapa);	
		initGUI();
		
		setLocationRelativeTo(null);
		setResizable(false);
		setVisible(true);
		
	}
	
	private void initGUI() {
		try {
			setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
			getContentPane().setLayout(null);
			
			
			this.setPreferredSize(new java.awt.Dimension(800, 634));
			getContentPane().setBackground(new java.awt.Color(107,136,255));
			{
				contenedorPersonaje = new JPanel();
				getContentPane().add(contenedorPersonaje);
				contenedorPersonaje.setDoubleBuffered(true);
				contenedorPersonaje.setLayout(null);
				contenedorPersonaje.setBounds(0, 0, 800, 600);
				contenedorPersonaje.setEnabled(false);
				contenedorPersonaje.setBackground(new java.awt.Color(107,136,255));
				contenedorPersonaje.setOpaque(false);
			}
			{
				
				panelElementos = new JPanel();
				getContentPane().add(panelElementos);
				panelElementos.setBounds(1, 1, 788, 599);
				panelElementos.setDoubleBuffered(true);
				panelElementos.setLayout(null);
				panelElementos.setOpaque(false);
				panelElementos.setAutoscrolls(true);
				panelElementos.setPreferredSize(new java.awt.Dimension(788, 599));

			}
			{
				panel = new JPanel();
				getContentPane().add(panel);
				panel.setLayout(null);
				panel.setBackground(new java.awt.Color(107,136,255));
				panel.setBounds(1, 1, 779, 591);
				panel.setDoubleBuffered(false);
				panel.setOpaque(false);
				{
					imageBackground = new JLabel();
					panel.add(imageBackground);
					imageBackground.setIcon(convertirIcono("Escenario/fondo.png"));
					imageBackground.setBounds(0, 0, 8772, 600);
					imageBackground.setBackground(new java.awt.Color(107,136,255));
				}
			}

			this.addKeyListener(new KeyAdapter() {
				
				public void keyReleased(KeyEvent evt) {
					thisKeyReleased(evt);
					
				}
				public void keyPressed(KeyEvent evt) {
					thisKeyPressed(evt);
				}
			});

			
			mario = new MarioChico();
			this.contenedorPersonaje.add(this.mario.getGrafica());
			this.mario.getGrafica().setHorizontalAlignment(SwingConstants.CENTER);
			
			this.hiloMario = new Thread((MarioChico)mario);
			this.hiloMario.start();

			gravedad = new Gravedad(mario,nivel);
			
			hiloGravedad = new Thread(gravedad);
			hiloGravedad.start();


			this.hiloJuego = new Thread(this);
			this.hiloJuego.start();
						
			pack();
			this.setSize(800, 634);
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
    
	private void actualizarElementosJuego(){
		
		ElementoJuego elemento = null;
		int posx, posy;
		
		for (int i = 0; i < nivel.getCantFilas(); i++){
			for (int j = 0; j < 14 ; j++) {
				elemento = nivel.get(i,j);
				if (elemento != null && !elemento.esTransitable()){
					
					posx = 250 + (elemento.getPos().getX() - mario.getPos().getX())*32;
					posy = 580 - (elemento.getPos().getY())*32;
				
					elemento.getGrafica().setBounds(posx,posy, 32, 32);
				
					contenedorPersonaje.add(elemento.getGrafica());
					
				}
				
			}
		
		}
	}
		
	public void run() {
		try {
			while(!findejuego && mario.getPos().getX() < nivel.getCantFilas()-1){
				
				findejuego = mario.getPos().getY() == 0;
				
				mario.getGrafica().setBounds(245, (575 - (mario.getPos().getY() * 32)), 46, 46);
				actualizarElementosJuego();
				
				contenedorPersonaje.repaint();
				
				Thread.sleep(30);
				
				}
			
			JuegoTerminado();			
		} catch(InterruptedException e) {
			e.printStackTrace();
		}
		
	}
	
	private void thisKeyPressed(KeyEvent evt){
		if(mario.getPos().getY() > 0){
			if(evt.getKeyCode()== KeyEvent.VK_UP){
				if (!this.bloquearSaltar)
					if(!nivel.get(mario.getPos().getX(), mario.getPos().getY()-1).esTransitable()){
						
						bloquearSaltar = true;
						saltar = new ActualizadorSaltar(imageBackground);
						saltar.start();
						
						this.mario.saltar();
						
						if(this.bloquearAvanzar){
							this.mario.irDerecha();
						}
						else
							if(this.bloquearRetroceder){
								this.mario.irIzquierda();
							}
						}
			}
			else{
				
				if(evt.getKeyCode()== KeyEvent.VK_RIGHT && !this.bloquearAvanzar && mario.getPos().getX() < 250){
						
						mario.irDerecha();
						bloquearAvanzar = true;
						avanzar = new ActualizadorAvanzar(imageBackground);
						avanzar.start();
				}
				
				if(evt.getKeyCode()== KeyEvent.VK_LEFT && !this.bloquearRetroceder && mario.getPos().getX() > 0){
								
								mario.irIzquierda();
								bloquearRetroceder = true;
								retroceder = new ActualizadorRetroceder(imageBackground);
								retroceder.start();
							}
			}
				
		}
	}
	
	
	
	private void thisKeyReleased(KeyEvent evt) {
		switch (evt.getKeyCode()){
			case KeyEvent.VK_RIGHT:
			{	if(bloquearAvanzar){
					this.bloquearAvanzar = false;	
					avanzar = null;
					mario.quieto();
				}
				break;
			}
			case KeyEvent.VK_LEFT:
			{	if(bloquearRetroceder){
					this.bloquearRetroceder = false;
					retroceder = null;
					mario.quieto();
				}
				break;
			}
			case KeyEvent.VK_UP:
			{	if(bloquearSaltar){
					this.bloquearSaltar = false;
				}
				break;
			}
		}
	}
	
	private Icon convertirIcono(String nombre){
		
		java.net.URL imageURLaux = getClass().getClassLoader().getResource("Recursos/Graficos/"+nombre);
		Icon imagen=new ImageIcon(imageURLaux);
		
		return imagen;
	}
	
	
	@SuppressWarnings("deprecation")
	private void JuegoTerminado(){		
		
		hiloMario.stop();
		hiloMario = null;
		
		bloquearAvanzar = false; 
		bloquearRetroceder = false;
		bloquearSaltar = false;
				
		avanzar = null;
		retroceder = null;
		saltar = null;
		
		hiloGravedad.stop();
		hiloGravedad = null;
		
		if(findejuego){
			JOptionPane.showMessageDialog(null, "Game Over","Termino el Juego!", 0);
			mario.DecrementarVidas();
		}
		else
			JOptionPane.showMessageDialog(null, "Felicitaciones ha ganado", "*** FELICITACIONES ***", 1);		
		
		setVisible(false);
		
		
		hiloJuego.stop();
		hiloJuego = null;
		
		
	}
	
	private class ActualizadorAvanzar extends Thread {
		protected JLabel level;
		
		public ActualizadorAvanzar(JLabel level)
		{
			this.level = level;
		}
		
		public void run()
		{
			while (mario.getPos().getX() < nivel.getCantFilas() && bloquearAvanzar)
			{
				try
				{
					
					this.level.setLocation(this.level.getLocation().x - 30,
										   this.level.getLocation().y);
					Thread.sleep(100);
				} catch (Exception e)
				{
					
				}
			}
		}
	}
	
	private class ActualizadorRetroceder extends Thread {
		protected JLabel level;
		
		public ActualizadorRetroceder(JLabel level)
		{
			this.level = level;
		}
		
		public void run()
		{
			while (mario.getPos().getX() > 0 && bloquearRetroceder)
			{
				try
				{
					
					this.level.setLocation(this.level.getLocation().x + 30,
										   this.level.getLocation().y);
					Thread.sleep(100);
				} catch (Exception e)
				{
					
				}
			}
		}

	}
	
	private class ActualizadorSaltar extends Thread {
		@SuppressWarnings("unused")
		protected JLabel level;
		
		public ActualizadorSaltar(JLabel level)
		{
			this.level = level;
		}
		
		
		
		@SuppressWarnings("deprecation")
		public void run()
		{	
			hiloGravedad.suspend();
			
			if( bloquearSaltar ){
				hiloGravedad.interrupt();
				for( int i = 0; i < 5; i++ )
				{
					try
					{
						if(nivel.get(mario.getPos().getX(), mario.getPos().getY()+1).esTransitable()){
							mario.getPos().setY(mario.getPos().getY()+1);
			
							Thread.sleep(60);
						}
					} catch (Exception e)
					{
					}
				}
				
				for( int i = 0; i < 5; i++ )
				{
					try
					{
						if(nivel.get(mario.getPos().getX(), mario.getPos().getY()-1).esTransitable()){
							mario.getPos().setY(mario.getPos().getY()-1);
							
							Thread.sleep(25);
					}
					} catch (Exception e)
					{
					}
				}
			}
			hiloGravedad.resume();
		}
	}
}